package think.in.java.concurrency.practise.exec8.ForNotify;

import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: Richard
 * Date: 8/1/11
 * Time: 7:16 AM
 * To change this template use File | Settings | File Templates.
 */
public class Waiter implements Runnable {
    private Restrant restrant;
    private static Object notifier = new Object();

    public static void setNotifier(Object notifier) {
        Waiter.notifier = notifier;
    }

    private enum status {Servering, delivering};


    private List list = Collections.synchronizedList(new ArrayList());
    private int waiterNum = 0;

    public Waiter(Restrant restrant , int waiterNum) {
        this.setRestrant(restrant);
        this.waiterNum = waiterNum;
    }

    public static Object getNotifier() {
        return notifier;
    }

    public int getWaiterNum() {
        return waiterNum;
    }

    public void setWaiterNum(int waiterNum) {
        this.waiterNum = waiterNum;
    }

    public Restrant getRestrant() {
        return restrant;
    }

    public void setRestrant(Restrant restrant) {
        this.restrant = restrant;
    }

    public void getReady() {

        try {
            Date date = new Date();
            System.out.println(this + "start to prepare ! "+ "datetime:" + date);

            Thread.sleep(100);
            getRestrant().getWaiterCountDown().countDown();
            System.out.println(this + "get ready!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public void run() {
        getReady();
        try {
            while (!Thread.interrupted()) {
                work();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }

    public synchronized void work() throws InterruptedException {
         if (getRestrant().getCustomers().size() == 0 && getRestrant().getFoods().size() == 0) {
             synchronized (notifier) {
                 notifier.wait();
             }

                } else {
                    deliverFood();
                    serviceCustomer();
                }
    }

    public void deliverFood() throws InterruptedException {
        Food food = getRestrant().popFood();
        if(food==null){
            return;
        }
        Chef chef = food.getChef();
        Customer customer = food.getCustomer();
        Boolean isSatisfied = false;
        int sleepTime = new Random().nextInt(100);

        System.out.println(this + "delivering food: from : " + chef + " to :" + customer);
        Thread.sleep(sleepTime);
        System.out.println(this + "delivered food: from : " + chef + " to :" + customer + " take " + sleepTime);
        isSatisfied = getRestrant().removeWaitingDeliverCustomers(customer);
        if (!isSatisfied) {
            System.out.println(this + "!The " + customer + " is not Satisfy ! Food wasted !");
        }
        else {
            System.out.println("!Satisfied The " + customer + " !");
        }
        return;


    }

    public void serviceCustomer() throws InterruptedException {
        Customer customer = getRestrant().popCustomers();
        if (customer == null) {
            return;
        }
        System.out.println(this + "service customer : " + customer);
        int sleepTime = new Random().nextInt(100);
        Thread.sleep(sleepTime);
        customer.setStatus(Customer.Status.waitingForFood);
        getRestrant().putWaitingFoodCustomers(customer);
        synchronized (Chef.getNotifier()){
            Chef.getNotifier().notifyAll();
        }

        System.out.println(this + "service customer : " + customer + " finished for " + sleepTime);


    }


    public String toString() {
        return "waiter : " + waiterNum + ": ";
    }

}
